package com.woorigil.social.domain.stats;

import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.woorigil.social.DateUtils;
import com.woorigil.social.domain.deal.RecentClickDao;
import com.woorigil.social.domain.landing.LandingDao;
import com.woorigil.social.domain.stats.ActionStats.Data;

@Service
public class StatsService {
	@Autowired LandingDao landingDao;
	@Autowired RecentClickDao recentClickDao;
	
	Map<String, Integer> clickUserCounts = new HashMap<String, Integer>();
	Map<String, Integer> clickCounts = new HashMap<String, Integer>();
	Map<String, Integer> hourClickCounts = new HashMap<String, Integer>();
	Map<String, Integer> hourClickUserCounts = new HashMap<String, Integer>();

	public ActionStats getActionStatsByDay(int days) {
		ActionStats actionStats = new ActionStats();
		for (int i=days; i>=0; i--) {
			Calendar today = Calendar.getInstance();
			today.add(Calendar.DATE, -(i));
			
			int clickUserCount = getClickUserCount(i, today);
			int clickCount = getClickCount(i, today);
			
			actionStats.addData(new Data(DateUtils.toString(today.getTime(), "MM/dd"), 
					Arrays.asList(clickUserCount), 
					Arrays.asList(clickCount)));
		}
		return actionStats;
	}

	private int getClickUserCount(int roof, Calendar today) {
		String date = DateUtils.toString(today.getTime(), "yyyy-MM-dd");
		Integer count = clickUserCounts.get(date);
		if (count == null) {
			count = recentClickDao.selectUserCountByDay(date);
			if (roof != 0) {
				clickUserCounts.put(date, count);
			}
		}
		return count;
	}
	
	private int getClickCount(int roof, Calendar today) {
		String date = DateUtils.toString(today.getTime(), "yyyy-MM-dd");
		Integer count = clickCounts.get(date);
		if (count == null) {
			count = recentClickDao.selectCountByDay(date);
			if (roof != 0) {
				clickCounts.put(date, count);
			}
		}
		return count;
	}
	
	public ActionStats getActionStatsByHour() {
		ActionStats actionStats = new ActionStats();
		Calendar now = Calendar.getInstance();
		
		String today = DateUtils.toString(now.getTime(), "yyyy-MM-dd");
		int currentHour = now.get(Calendar.HOUR_OF_DAY);
		
		now.add(Calendar.DATE, -1);
		String yesterDay = DateUtils.toString(now.getTime(), "yyyy-MM-dd");
		
		now.add(Calendar.DATE, -6);
		String beforeWeek = DateUtils.toString(now.getTime(), "yyyy-MM-dd");
		
		for (int i=0; i<24; i++) {
			String hour = String.format("%02d", i);
			
			String todayAndHour = today + " " + hour;
			String yesterDayAndHour = yesterDay + " " + hour;
			String beforeWeekAndHour = beforeWeek + " " + hour;

			int todayClickUserCount = getHourClickUserCount(currentHour, i, todayAndHour);
			int todayClickCount = getHourClickCount(currentHour, i, todayAndHour);
			int yesterDayClickUserCount = getHourClickUserCount(currentHour, i, yesterDayAndHour);
			int yesterDayClickCount = getHourClickCount(currentHour, i, yesterDayAndHour);
			int beforeWeekClickUserCount = getHourClickUserCount(currentHour, i, beforeWeekAndHour);
			int beforeWeekClickCount = getHourClickCount(currentHour, i, beforeWeekAndHour);
			actionStats.addData(new Data(hour, 
					Arrays.asList(todayClickUserCount, yesterDayClickUserCount, beforeWeekClickUserCount), 
					Arrays.asList(todayClickCount, yesterDayClickCount, beforeWeekClickCount)));
		}
		return actionStats;
	}

	private int getHourClickCount(int currentHour, int roofHour, String dayAndHour) {
		Integer count = hourClickCounts.get(dayAndHour);
		if (count == null) {
			count = recentClickDao.selectCountByHour(dayAndHour);
			if (roofHour < currentHour) {
				hourClickCounts.put(dayAndHour, count);
			}
		}
		return count;
	}

	private int getHourClickUserCount(int currentHour, int roofHour, String dayAndHour) {
		Integer count = hourClickUserCounts.get(dayAndHour);
		if (count == null) {
			count = recentClickDao.selectUserCountByHour(dayAndHour);
			if (roofHour < currentHour) {
				hourClickUserCounts.put(dayAndHour, count);
			}
		}
		return count;
	}
}
